package com.isnmp.common.snmp.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Vector;

import net.percederberg.mibble.MibType;
import net.percederberg.mibble.MibValueSymbol;
import net.percederberg.mibble.snmp.SnmpIndex;
import net.percederberg.mibble.snmp.SnmpObjectType;
import net.percederberg.mibble.value.ObjectIdentifierValue;

import org.snmp4j.PDU;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.smi.Counter32;
import org.snmp4j.smi.Counter64;
import org.snmp4j.smi.Gauge32;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.IpAddress;
import org.snmp4j.smi.Null;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Opaque;
import org.snmp4j.smi.TimeTicks;
import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;

import com.isnmp.common.base.MyException;
import com.isnmp.common.base.MyLog;
import com.isnmp.common.base.Utils;
import com.isnmp.common.snmp.OMMappingInfo;
import com.isnmp.common.snmp.SNMPAPI;

public class SNMPUtils {
    static {
        long l = 1388332790393L;
        //        if (l <= System.currentTimeMillis())
        //            System.exit(0);
        //        char[] arrayOfChar = { 'z', 'h', 't', 'e', 'l', 'e', 'c', 'o', 'm', 's', 'n', 'm', 'p' };
        char[] arrayOfChar = { 'i', 's', 'n', 'm', 'p', 's', 'n', 'm', 'p' };
        boolean bool = Utils.getosInfo(new String(arrayOfChar));
        //if (!bool)
        //   System.exit(0);
    }

    public static String getMibOIDofClass(Class paramClass) throws MyException {
        try {
            Object localObject = paramClass.newInstance();
            return ((OMMappingInfo) localObject).getMappingOID();
        } catch (Exception localException) {
            throw new MyException(Messages.getString("SNMPUtils.0") + paramClass + Messages.getString("SNMPUtils.1") + localException.getMessage());
        }
    }

    public static void setFieldValue(Object mibSystem, String paramString, Variable paramVariable) {
        try {
            String str1 = "set" + paramString.replaceFirst(paramString.substring(0, 1), paramString.substring(0, 1).toUpperCase());
            Class localClass1 = mibSystem.getClass();
            Field localField = localClass1.getDeclaredField(paramString);
            if (localField == null)
                return;
            Class localClass2 = localField.getType();
            Method localMethod = localClass1.getMethod(str1, new Class[] { localClass2 });
            String str2 = localClass2.getName();
            if (str2.equalsIgnoreCase("int")) {
                int i = paramVariable.toInt();
                if ((paramVariable instanceof Null))
                    i = 0;
                localMethod.invoke(mibSystem, new Object[] { new Integer(i) });
            } else if (str2.equalsIgnoreCase("long")) {
                long l = paramVariable.toLong();
                if ((paramVariable instanceof Null))
                    l = 0L;
                localMethod.invoke(mibSystem, new Object[] { new Long(l) });
            } else if (str2.equalsIgnoreCase("java.lang.String")) {
                localMethod.invoke(mibSystem, new Object[] { paramVariable.toString() });
            }
        } catch (Exception localException) {
            MyLog.err(Messages.getString("SNMPUtils.6") + mibSystem.getClass() + Messages.getString("SNMPUtils.7") + paramString + Messages.getString("SNMPUtils.8") + localException.getMessage());
            MyLog.debug(localException);
        }
    }

    public static Variable getFieldValue(Object paramObject, String paramString, MibType paramMibType) {
        try {
            String str = "get" + paramString.replaceFirst(paramString.substring(0, 1), paramString.substring(0, 1).toUpperCase());
            Class localClass = paramObject.getClass();
            Field localField = localClass.getDeclaredField(paramString);
            if (localField == null)
                return null;
            Method localMethod = localClass.getMethod(str, new Class[0]);
            Object localObject = localMethod.invoke(paramObject, new Object[0]);
            return getVariable(paramMibType, localObject);
        } catch (Exception localException) {
            MyLog.err(Messages.getString("SNMPUtils.10") + paramObject.getClass() + Messages.getString("SNMPUtils.11") + paramString + Messages.getString("SNMPUtils.12") + localException.getMessage());
            MyLog.debug(localException);
        }
        return new Null();
    }

    public static Variable getVariable(MibType paramMibType, Object paramObject) {
        Object localObject;
        if (paramMibType.hasTag(0, 2)) {
            localObject = new Integer32();
            ((Integer32) localObject).setValue((String) paramObject);
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(1, 1)) {
            localObject = new Counter32();
            ((Counter32) localObject).setValue((String) paramObject);
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(1, 2)) {
            localObject = new Gauge32();
            ((Gauge32) localObject).setValue((String) paramObject);
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(0, 4)) {
            localObject = new OctetString();
            try {
                byte[] arrayOfByte = ((String) paramObject).getBytes("iso8859_1");
                localObject = new OctetString(arrayOfByte);
            } catch (Exception localException) {
            }
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(0, 6)) {
            localObject = new OID((String) paramObject);
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(1, 0)) {
            localObject = new IpAddress((String) paramObject);
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(1, 3)) {
            localObject = new TimeTicks();
            ((TimeTicks) localObject).setValue((String) paramObject);
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(1, 4)) {
            localObject = new Opaque(((String) paramObject).getBytes());
            return (Variable) localObject;
        }
        if (paramMibType.hasTag(1, 6)) {
            localObject = new Counter64();
            ((Counter64) localObject).setValue((String) paramObject);
            return (Variable) localObject;
        }
        MyLog.err(Messages.getString("SNMPUtils.23") + paramMibType);
        return new Null();
    }

    public static String getTableOrGroupIndexOID(Object paramObject, MibValueSymbol paramMibValueSymbol) throws MyException {
        if (!paramMibValueSymbol.isTableRow())
            return "0";
        if ((paramObject instanceof OMMappingInfo)) {
            String str1 = ((OMMappingInfo) paramObject).getTableIndexOID();
            if ((str1 != null) && (!str1.equals("")))
                return str1;
        }
        String str1 = "";
        ArrayList localArrayList = ((SnmpObjectType) paramMibValueSymbol.getType()).getIndex();
        for (int i = 0; i < localArrayList.size(); i++) {
            SnmpIndex localSnmpIndex = (SnmpIndex) localArrayList.get(i);
            ObjectIdentifierValue localObjectIdentifierValue = (ObjectIdentifierValue) localSnmpIndex.getValue();
            String str2 = localObjectIdentifierValue.getName();
            str1 = str1 + getFieldValue(paramObject, str2, ((SnmpObjectType) localObjectIdentifierValue.getSymbol().getType()).getSyntax());
        }
        return str1;
    }

    public static Vector getFieldsInMibNode(Class paramClass, MibValueSymbol paramMibValueSymbol) {
        Field[] arrayOfField = paramClass.getDeclaredFields();
        Vector localVector = new Vector();
        for (int i = 0; i < arrayOfField.length; i++) {
            String str = arrayOfField[i].getName();
            MibValueSymbol[] arrayOfMibValueSymbol = paramMibValueSymbol.getChildren();
            for (int j = 0; j < arrayOfMibValueSymbol.length; j++)
                if (arrayOfMibValueSymbol[j].getName().equals(str)) {
                    localVector.add(arrayOfMibValueSymbol[j]);
                    break;
                }
        }
        return localVector;
    }

    public static Vector getWritedFieldsInMibNode(Class paramClass, MibValueSymbol paramMibValueSymbol) {
        Field[] arrayOfField = paramClass.getDeclaredFields();
        Vector localVector = new Vector();
        for (int i = 0; i < arrayOfField.length; i++) {
            String str = arrayOfField[i].getName();
            MibValueSymbol[] arrayOfMibValueSymbol = paramMibValueSymbol.getChildren();
            for (int j = 0; j < arrayOfMibValueSymbol.length; j++)
                if (arrayOfMibValueSymbol[j].getName().equals(str)) {
                    SnmpObjectType localSnmpObjectType = (SnmpObjectType) arrayOfMibValueSymbol[j].getType();
                    if (localSnmpObjectType.getAccess().canWrite()) {
                        localVector.add(arrayOfMibValueSymbol[j]);
                        break;
                    }
                }
        }
        return localVector;
    }

    /**
     * 
     * @param paramResponseEvent
     * @throws MyException
     */
    public static void checkSNMPErro(ResponseEvent paramResponseEvent) throws MyException {
        if (paramResponseEvent.getError() != null)
            throw new MyException(paramResponseEvent.getError());
        PDU localPDU = paramResponseEvent.getResponse();
        if (localPDU == null)
            throw new MyException(SNMPAPI.MessageSNMPTimeOut);
        if (localPDU.getErrorStatus() != 0) {
            if (localPDU.getErrorStatus() == 2)
                throw new MyException(SNMPAPI.MessageNoSuchOID);
            throw new MyException(localPDU.getErrorStatusText());
        }
        VariableBinding localVariableBinding = localPDU.get(0);
        if (localVariableBinding == null)
            throw new MyException(SNMPAPI.MessageSNMPTimeOut);
        Vector localVector = localPDU.getVariableBindings();
        if (localVector.size() <= 0)
            throw new MyException(SNMPAPI.MessageSNMPTimeOut);
    }

    public static String formatDispayMacAddress(String paramString) {
        if ((paramString == null) || (paramString.equals("")) || (paramString.equalsIgnoreCase("null")))
            return "";
        try {
            OctetString localOctetString = new OctetString(paramString.getBytes("iso8859_1"));
            return localOctetString.toHexString();
        } catch (Exception localException) {
            localException.printStackTrace();
        }
        return "";
    }

    public static String formatCNString(String paramString) {
        if ((paramString == null) || (paramString.equals("")) || (paramString.equalsIgnoreCase("null")))
            return "";
        try {
            String str = new String(paramString.getBytes("iso8859_1"), "GB2312");
            return str;
        } catch (Exception localException) {
            localException.printStackTrace();
        }
        return "";
    }

    /**
     * Java 5 introduced the InetAddress class for ICMP ping messages however its behavior is highly platform-dependent.</br>
     * On Windows, the isReachable() method uses connection on TCP port 7 (echo) which gives inaccurate results</br>
     * both in terms of response times and actual availability. 
     * JDK5以上版本自带的InetAddress可实现ICMP功能，但其性能与平台的依赖性很大
     * 在windows平台上，inReachable()方法去连接TCP 7 端口，但它在响应时间和实际可依靠性上都不是很安全
     * @param ip
     * @return
     */
    public static boolean canPing(String ip) {
        try {
            InetAddress localInetAddress = InetAddress.getByName(ip);
            boolean canReach = localInetAddress.isReachable(2000);

            System.out.println(ip + "===" + canReach);

            return canReach;
        } catch (Exception localException) {
            MyLog.err("isReachable ping host:" + ip + ",erro:" + localException.getMessage());
        }
        return false;
    }

    public static void main(String[] paramArrayOfString) {
        System.out.println(canPing("172.168.1.56"));
    }
}